from flask_restx import Api, Resource, fields, reqparse
from flask import Blueprint, send_file, current_app
import json
import yaml
import os
import tempfile

# 创建一个蓝图
blueprint = Blueprint('api_docs', __name__, url_prefix='/api/docs')
api = Api(blueprint,
    title='Service Platform API',
    version='1.0',
    description='生活服务平台 API 文档',
    doc='/swagger'
)

# 定义认证头
authorizations = {
    'Bearer': {
        'type': 'apiKey',
        'in': 'header',
        'name': 'Authorization',
        'description': "使用Bearer token进行认证。示例: 'Bearer {token}'"
    }
}
api.authorizations = authorizations

# 定义命名空间
auth_ns = api.namespace('auth', description='认证相关操作')
user_ns = api.namespace('users', description='用户管理')
service_ns = api.namespace('services', description='服务管理')
provider_ns = api.namespace('providers', description='服务提供者管理')
category_ns = api.namespace('categories', description='服务类别管理')
rating_ns = api.namespace('ratings', description='评价管理')
carousel_ns = api.namespace('carousel', description='轮播图管理')
profile_ns = api.namespace('profile', description='个人中心')
settings_ns = api.namespace('settings', description='设置管理')

# 基础响应模型
response_model = api.model('Response', {
    'status': fields.String(description='响应状态：success 或 error'),
    'message': fields.String(description='响应消息'),
    'data': fields.Raw(description='响应数据')
})

# 认证相关模型
login_model = api.model('Login', {
    'username': fields.String(required=True, description='用户名'),
    'password': fields.String(required=True, description='密码')
})

register_model = api.model('Register', {
    'username': fields.String(required=True, description='用户名'),
    'email': fields.String(required=True, description='邮箱'),
    'password': fields.String(required=True, description='密码')
})

# 用户相关模型
user_model = api.model('User', {
    'id': fields.Integer(description='用户ID'),
    'username': fields.String(description='用户名'),
    'email': fields.String(description='邮箱'),
    'is_admin': fields.Boolean(description='是否为管理员'),
    'created_at': fields.DateTime(description='创建时间')
})

# 服务相关模型
service_model = api.model('Service', {
    'id': fields.Integer(description='服务ID'),
    'title': fields.String(required=True, description='服务标题'),
    'description': fields.String(description='服务描述'),
    'provider_id': fields.Integer(required=True, description='服务提供者ID'),
    'category_id': fields.Integer(required=True, description='服务类别ID'),
    'image_url': fields.String(description='图片URL'),
    'video_url': fields.String(description='视频URL'),
    'audio_url': fields.String(description='音频URL'),
    'created_at': fields.DateTime(description='创建时间')
})

# 服务类别模型
category_model = api.model('Category', {
    'id': fields.Integer(description='类别ID'),
    'name': fields.String(required=True, description='类别名称'),
    'description': fields.String(description='类别描述')
})

# 服务提供者模型
provider_model = api.model('Provider', {
    'id': fields.Integer(description='提供者ID'),
    'name': fields.String(required=True, description='提供者名称'),
    'description': fields.String(description='提供者描述'),
    'category_id': fields.Integer(required=True, description='所属类别ID')
})

# 评价模型
rating_model = api.model('Rating', {
    'id': fields.Integer(description='评价ID'),
    'provider_id': fields.Integer(required=True, description='服务提供者ID'),
    'user_id': fields.Integer(description='用户ID'),
    'rating': fields.Integer(required=True, description='评分(1-5)'),
    'comment': fields.String(description='评价内容')
})

# 轮播图模型
carousel_model = api.model('Carousel', {
    'id': fields.Integer(description='轮播图ID'),
    'image_url': fields.String(required=True, description='图片URL'),
    'link': fields.String(description='链接URL')
})

# 设置模型
settings_model = api.model('Settings', {
    'old_password': fields.String(required=True, description='原密码'),
    'new_password': fields.String(required=True, description='新密码')
})

# 在已有的用户模型基础上添加管理员创建模型
admin_create_model = api.model('AdminCreate', {
    'username': fields.String(required=True, description='管理员用户名'),
    'email': fields.String(required=True, description='管理员邮箱'),
    'password': fields.String(required=True, description='管理员密码')
})

# 文件上传相关的模型和响应
upload_parser = reqparse.RequestParser()
upload_parser.add_argument('file', 
    type=reqparse.FileStorage, 
    location='files', 
    required=True, 
    help='图片文件')
upload_parser.add_argument('folder', 
    type=str, 
    location='form',
    default='images',
    help='保存的子文件夹(services/carousel/images)')

upload_response = api.model('UploadResponse', {
    'status': fields.String(description='响应状态'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(api.model('UploadData', {
        'url': fields.String(description='文件访问URL')
    }))
})

# 修改服务创建模型
service_create_model = api.model('ServiceCreate', {
    'title': fields.String(description='服务标题'),
    'description': fields.String(description='服务描述'),
    'provider_id': fields.Integer(description='服务提供者ID'),
    'category_id': fields.Integer(description='服务类别ID'),
    'image': fields.Raw(description='图片文件(multipart/form-data)'),
    'video_url': fields.String(description='视频URL'),
    'audio_url': fields.String(description='音频URL')
})

# 修改轮播图创建模型
carousel_create_model = api.model('CarouselCreate', {
    'image': fields.Raw(description='图片文件(multipart/form-data)'),
    'link': fields.String(description='链接URL')
})

# API路由定义
@auth_ns.route('/auth/login')
class Login(Resource):
    @auth_ns.expect(login_model)
    @auth_ns.response(200, '登录成功', response_model)
    @auth_ns.response(401, '登录失败')
    @auth_ns.doc('用户登录')
    def post(self):
        """用户登录接口"""
        pass

@auth_ns.route('/auth/register')
class Register(Resource):
    @auth_ns.expect(register_model)
    @auth_ns.response(201, '注册成功', response_model)
    @auth_ns.response(400, '注册失败')
    @auth_ns.doc('用户注册')
    def post(self):
        """用户注册接口"""
        pass

@service_ns.route('/')
class ServiceList(Resource):
    @service_ns.doc('获取服务列表')
    @service_ns.response(200, '成功', response_model)
    def get(self):
        """获取服务列表"""
        pass

    @service_ns.expect(service_model)
    @service_ns.response(201, '创建成功', response_model)
    @service_ns.doc(security='Bearer')
    def post(self):
        """创建新服务"""
        pass

@service_ns.route('/<int:id>')
class ServiceDetail(Resource):
    @service_ns.doc('获取服务详情')
    @service_ns.response(200, '成功', response_model)
    @service_ns.response(404, '服务不存在')
    def get(self, id):
        """获取服务详情"""
        pass

@rating_ns.route('/')
class RatingList(Resource):
    @rating_ns.doc('获取评价列表')
    @rating_ns.response(200, '成功', response_model)
    def get(self):
        """获取评价列表"""
        pass

    @rating_ns.expect(rating_model)
    @rating_ns.response(201, '评价成功', response_model)
    @rating_ns.doc(security='Bearer')
    def post(self):
        """添加评价"""
        pass

@profile_ns.route('/')
class Profile(Resource):
    @profile_ns.doc('获取个人信息')
    @profile_ns.response(200, '成功', response_model)
    @profile_ns.doc(security='Bearer')
    def get(self):
        """获取个人信息"""
        pass

@settings_ns.route('/password')
class PasswordSettings(Resource):
    @settings_ns.expect(settings_model)
    @settings_ns.response(200, '修改成功', response_model)
    @settings_ns.doc(security='Bearer')
    def put(self):
        """修改密码"""
        pass

@carousel_ns.route('/')
class CarouselList(Resource):
    @carousel_ns.doc('获取轮播图列表')
    @carousel_ns.response(200, '成功', response_model)
    def get(self):
        """获取轮播图列表"""
        pass

    @carousel_ns.expect(carousel_model)
    @carousel_ns.response(201, '创建成功', response_model)
    @carousel_ns.doc(security='Bearer')
    def post(self):
        """添加轮播图"""
        pass

@user_ns.route('/admin')
class AdminCreate(Resource):
    @user_ns.expect(admin_create_model)
    @user_ns.response(201, '创建成功', response_model)
    @user_ns.response(400, '创建失败')
    @user_ns.doc('创建管理员', security='Bearer')
    def post(self):
        """创建新管理员账号（需要超级管理员权限）"""
        pass

@api.route('/upload')
class FileUpload(Resource):
    @api.expect(upload_parser)
    @api.response(201, '上传成功', upload_response)
    @api.response(400, '上传失败')
    @api.doc('上传文件',
        description='上传图片文件并返回访问URL。支持的文件类型：png, jpg, jpeg, gif')
    def post(self):
        """
        上传文件接口
        
        使用 multipart/form-data 格式上传文件：
        - file: 图片文件
        - folder: 保存的子文件夹(可选，默认为 images)
          - services: 服务相关图片
          - carousel: 轮播图
          - images: 其他图片
        
        返回数据中的 url 字段为文件访问路径
        """
        pass

# 下载API文档的路由
@blueprint.route('/download/json')
def download_json():
    """下载 JSON 格式的 API 文档"""
    spec = api.__schema__
    
    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.json') as temp:
        json.dump(spec, temp, indent=2)
        temp_path = temp.name
    
    try:
        return send_file(
            temp_path,
            as_attachment=True,
            download_name='swagger_spec.json',
            mimetype='application/json'
        )
    finally:
        try:
            os.unlink(temp_path)
        except:
            pass

@blueprint.route('/download/yaml')
def download_yaml():
    """下载 YAML 格式的 API 文档"""
    spec = api.__schema__
    
    with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.yaml') as temp:
        yaml.dump(spec, temp, allow_unicode=True)
        temp_path = temp.name
    
    try:
        return send_file(
            temp_path,
            as_attachment=True,
            download_name='swagger_spec.yaml',
            mimetype='application/yaml'
        )
    finally:
        try:
            os.unlink(temp_path)
        except:
            pass 